//@author A0096950U

#include "Display.h"

Display::Display(void) : logger(Logger::getInstance()) {
}

bool Display::sortTaskTime(const Task& task1, const Task& task2) {

	string task1StartTime  = task1.getStartTime();
	string task1EndTime  = task1.getEndTime();
	string task2StartTime  = task2.getStartTime();
	string task2EndTime  = task2.getEndTime();

	return (task1StartTime < task2StartTime) || 
		(task1StartTime == task2StartTime && task1EndTime < task2EndTime);
}

bool Display::sortTaskDate(const Task& task1, const Task& task2) {

	string task1Date = task1.getDate();
	string task1Day = task1Date.substr(0,2);
	string task1Mon = task1Date.substr(2,2);
	string task1Year = task1Date.substr(4,4);

	string task2Date = task2.getDate();
	string task2Day = task2Date.substr(0,2);
	string task2Mon = task2Date.substr(2,2);
	string task2Year = task2Date.substr(4,4);

	return (task1Year < task2Year) ||
		(task1Year == task2Year && task1Mon < task2Mon) || 
		(task1Year == task2Year && task1Mon == task2Mon && task1Day < task2Day);
}

void Display::sortByTime() {

	if(!tasksDisplayed.empty()) {
		stable_sort(tasksDisplayed.begin(), tasksDisplayed.end(), sortTaskTime);
	}

	logger.log(LOG_DEBUGGING, "Display: Sorted display by time.");
}

void Display::sortByDate() {

	if(!tasksDisplayed.empty()) {
		stable_sort(tasksDisplayed.begin(), tasksDisplayed.end(), sortTaskDate);
	}

	logger.log(LOG_DEBUGGING, "Display: Sorted display by date.");
}

int Display::size() const {

	return tasksDisplayed.size();
}

void Display::push_back(const Task& taskToAdd) {

	tasksDisplayed.push_back(taskToAdd);

	logger.log(LOG_DEBUGGING, "Display: Added task to display.");
}

void Display::remove(int userIndex) {

	assert(userIndex > 0 && (unsigned) userIndex <= tasksDisplayed.size());

	tasksDisplayed.erase(tasksDisplayed.begin() + userIndex - 1);

	logger.log(LOG_DEBUGGING, "Display: Removed task from display.");
}

void Display::remove(string taskID) {

	bool found = false;
	unsigned index = 0;

	while(index < tasksDisplayed.size() && !found) {
		if(tasksDisplayed[index].getID() == taskID)	{
			found = true;
		}

		index++;
	}

	if(found) {
		remove(index);
	}
}

void Display::clear() {

	tasksDisplayed.clear();
}

void Display::modify(Task& newTask)  {

	bool found = false;
	string targetID = newTask.getID();

	for(unsigned i = 0; i < tasksDisplayed.size() && !found; i++) {
		if(tasksDisplayed[i].getID() == targetID) {
			tasksDisplayed[i] = newTask;
			found = true;
		}
	}
}

Task Display::getTask(int userIndex) const {

	assert(userIndex > 0 && (unsigned) userIndex <= tasksDisplayed.size());

	return tasksDisplayed[userIndex-1];
}

Task Display::getTask(string taskID) const {

	Task taskToReturn;
	bool found = false;

	for(unsigned i = 0; i < tasksDisplayed.size() && !found; i++) {
		if(tasksDisplayed[i].getID() == taskID)	{
			taskToReturn = tasksDisplayed[i];
			found = true;
		}
	}

	assert(found);

	return taskToReturn;
}

void Display::setTasksDisplayed(vector<Task>& newDisplay) {

	tasksDisplayed.clear();
	tasksDisplayed = newDisplay;
}

vector<Task> Display::getTasksDisplayed() const {

	return tasksDisplayed;
}

void Display::setStatus(int userIndex, TaskStatus newStatus) {

	tasksDisplayed[userIndex-1].setStatus(newStatus);
}